/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.security.service

import me.zhengjie.common.exception.BadRequestException
import org.springframework.security.core.userdetails.UsernameNotFoundException

import me.zhengjie.common.exception.EntityNotFoundException
import me.zhengjie.modules.security.service.dto.JwtUserDto
import me.zhengjie.modules.system.service.DataService
import me.zhengjie.modules.system.service.RoleService
import me.zhengjie.modules.system.service.UserService
import me.zhengjie.modules.system.service.dto.UserLoginDTO
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.stereotype.Service

/**
 * @author Zheng Jie
 * @date 2018-11-22
 */
@Service("userDetailsService")
class UserDetailsServiceImpl (
    private val userService: UserService? = null,
    private val roleService: RoleService? = null,
    private val dataService: DataService? = null,
    private val userCacheManager: UserCacheManager? = null
): UserDetailsService {
    override fun loadUserByUsername(username: String): JwtUserDto {
        var jwtUserDto: JwtUserDto? = userCacheManager!!.getUserCache(username)
        if (jwtUserDto == null) {
            val user: UserLoginDTO
            user = try {
                userService!!.getLoginData(username)!!
            } catch (e: EntityNotFoundException) {
                // SpringSecurity会自动转换UsernameNotFoundException为BadCredentialsException
                throw UsernameNotFoundException(username, e)
            }
            if (user == null) {
                throw UsernameNotFoundException("")
            } else {
                if (user.userDTO!!.enabled == false) {
                    throw BadRequestException("账号未激活！")
                }
                jwtUserDto = JwtUserDto(
                    user,
                    dataService!!.getDeptIds(user.userDTO)!!.map { it!!.toLong() },
                    roleService!!.mapToGrantedAuthorities(user.userDTO)!!.map { it!!}
                )
                // 添加缓存数据
                userCacheManager.addUserCache(username, jwtUserDto)
            }
        }
        return jwtUserDto
    }
}